package com.example.backend.service;

import com.example.backend.domain.enums.TicketStatus;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 工单状态机验证服务
 * 确保状态转换符合业务规则：新建→待处理→处理中→已解决→已关闭
 */
@Service
public class TicketStateMachineService {

    /**
     * 状态转换规则映射
     * key: 当前状态, value: 允许转换到的状态列表
     */
    private static final Map<TicketStatus, Set<TicketStatus>> STATE_TRANSITIONS = new HashMap<>();

    static {
        // 新建状态可以转换到：待处理、已关闭、已取消
        STATE_TRANSITIONS.put(TicketStatus.OPEN, Set.of(
            TicketStatus.IN_PROGRESS, 
            TicketStatus.CLOSED
        ));

        // 处理中状态可以转换到：已解决、已关闭、重新打开
        STATE_TRANSITIONS.put(TicketStatus.IN_PROGRESS, Set.of(
            TicketStatus.RESOLVED, 
            TicketStatus.CLOSED,
            TicketStatus.OPEN  // 重新打开
        ));

        // 已解决状态可以转换到：已关闭、重新打开
        STATE_TRANSITIONS.put(TicketStatus.RESOLVED, Set.of(
            TicketStatus.CLOSED,
            TicketStatus.OPEN  // 重新打开
        ));

        // 已关闭状态可以转换到：重新打开
        STATE_TRANSITIONS.put(TicketStatus.CLOSED, Set.of(
            TicketStatus.OPEN  // 重新打开
        ));
    }

    /**
     * 验证状态转换是否合法
     * 
     * @param currentStatus 当前状态
     * @param targetStatus 目标状态
     * @return 是否允许转换
     */
    public boolean isValidTransition(TicketStatus currentStatus, TicketStatus targetStatus) {
        if (currentStatus == null || targetStatus == null) {
            return false;
        }

        // 相同状态不需要转换
        if (currentStatus.equals(targetStatus)) {
            return true;
        }

        Set<TicketStatus> allowedTransitions = STATE_TRANSITIONS.get(currentStatus);
        return allowedTransitions != null && allowedTransitions.contains(targetStatus);
    }

    /**
     * 获取允许的状态转换列表
     * 
     * @param currentStatus 当前状态
     * @return 允许转换到的状态列表
     */
    public Set<TicketStatus> getAllowedTransitions(TicketStatus currentStatus) {
        if (currentStatus == null) {
            return Collections.emptySet();
        }

        Set<TicketStatus> allowedTransitions = STATE_TRANSITIONS.get(currentStatus);
        if (allowedTransitions == null) {
            return Collections.emptySet();
        }

        // 包含当前状态（表示可以保持当前状态）
        Set<TicketStatus> result = new HashSet<>(allowedTransitions);
        result.add(currentStatus);
        return result;
    }

    /**
     * 获取状态转换描述
     * 
     * @param currentStatus 当前状态
     * @param targetStatus 目标状态
     * @return 转换描述
     */
    public String getTransitionDescription(TicketStatus currentStatus, TicketStatus targetStatus) {
        if (!isValidTransition(currentStatus, targetStatus)) {
            return "无效的状态转换";
        }

        Map<String, String> descriptions = Map.of(
            "OPEN->IN_PROGRESS", "开始处理工单",
            "OPEN->CLOSED", "直接关闭工单",
            "IN_PROGRESS->RESOLVED", "标记工单已解决",
            "IN_PROGRESS->CLOSED", "关闭工单",
            "IN_PROGRESS->OPEN", "重新打开工单",
            "RESOLVED->CLOSED", "关闭已解决的工单",
            "RESOLVED->OPEN", "重新打开工单",
            "CLOSED->OPEN", "重新打开工单"
        );

        String key = currentStatus.name() + "->" + targetStatus.name();
        return descriptions.getOrDefault(key, "状态转换");
    }

    /**
     * 检查是否需要特殊权限进行状态转换
     * 
     * @param currentStatus 当前状态
     * @param targetStatus 目标状态
     * @return 是否需要特殊权限
     */
    public boolean requiresSpecialPermission(TicketStatus currentStatus, TicketStatus targetStatus) {
        // 关闭工单需要特殊权限
        if (targetStatus == TicketStatus.CLOSED) {
            return true;
        }

        // 重新打开工单需要特殊权限
        if (currentStatus == TicketStatus.CLOSED && targetStatus == TicketStatus.OPEN) {
            return true;
        }

        return false;
    }

    /**
     * 获取状态的工作流阶段
     * 
     * @param status 工单状态
     * @return 工作流阶段
     */
    public String getWorkflowStage(TicketStatus status) {
        if (status == null) {
            return "未知";
        }

        Map<TicketStatus, String> stages = Map.of(
            TicketStatus.OPEN, "新建",
            TicketStatus.IN_PROGRESS, "处理中",
            TicketStatus.RESOLVED, "已解决",
            TicketStatus.CLOSED, "已关闭"
        );

        return stages.getOrDefault(status, "未知");
    }

    /**
     * 检查状态转换是否需要通知相关人员
     * 
     * @param currentStatus 当前状态
     * @param targetStatus 目标状态
     * @return 是否需要通知
     */
    public boolean requiresNotification(TicketStatus currentStatus, TicketStatus targetStatus) {
        if (currentStatus == null || targetStatus == null) {
            return false;
        }

        // 状态发生变化时需要通知
        return !currentStatus.equals(targetStatus);
    }

    /**
     * 获取状态转换的业务规则说明
     * 
     * @return 业务规则说明
     */
    public String getBusinessRulesDescription() {
        return """
            工单状态转换业务规则：
            1. 新建(OPEN) → 待处理(IN_PROGRESS)：开始处理工单
            2. 新建(OPEN) → 已关闭(CLOSED)：直接关闭工单（需要权限）
            3. 处理中(IN_PROGRESS) → 已解决(RESOLVED)：标记工单已解决
            4. 处理中(IN_PROGRESS) → 已关闭(CLOSED)：关闭工单（需要权限）
            5. 处理中(IN_PROGRESS) → 新建(OPEN)：重新打开工单
            6. 已解决(RESOLVED) → 已关闭(CLOSED)：关闭已解决的工单
            7. 已解决(RESOLVED) → 新建(OPEN)：重新打开工单
            8. 已关闭(CLOSED) → 新建(OPEN)：重新打开工单（需要权限）
            """;
    }
}
